/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//-------------------------------------------------------//
// Spin Launcher (funnel-like object boosting you up)    //
//-------------------------------------------------------//

//# address-hook(0x028db8) end(0x028dde)
function void SpinLauncher.Init()
{
	objA0.mapping_offset = 0x227bc2
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x02ea)
	objA0.box_size.x = 0x20
	objA0.box_size.y = 0x20
	objA0.render_flags |= render_flag.WORLD
	objA0.sprite_priority = 0x80

	objA0.update_address = addressof(SpinLauncher.Update)
	SpinLauncher.Update()
}


//# address-hook(0x028de4) end(0x028e70)
function void SpinLauncher.Update()
{
	D1.u16 = 0x2b
	D2.u16 = 0x10
	D4.u16 = objA0.position.x.u16
	A2 = 0x028ff4
	A4 = A0 + 0x2e
	if (u8[A4] != 0)
	{
		--u8[A4]
	}
	else
	{
		u32 backupD1 = D1
		u32 backupD2 = D2
		u32 backupD3 = D3
		u32 backupD4 = D4

		A1 = 0xffffb000
		D6 = 3		// object.flag.P1_ON_OBJECT
		fn01dd24()
		if (D4.u16 == 0xfffe)
		{
			fn028e76()
		}

		D1 = backupD1
		D2 = backupD2
		D3 = backupD3
		D4 = backupD4
	}

	++A4
	if (u8[A4] != 0)
	{
		--u8[A4]
	}
	else
	{
		A1 = 0xffffb04a
		D6 = 4		// object.flag.P2_ON_OBJECT
		fn01dd24()
		if (D4.u16 == 0xfffe)
		{
			fn028e76()
		}
	}

	D6.u8 = objA0.flags2a & (object.flag.P1_ON_OBJECT | object.flag.P2_ON_OBJECT)
	if (D6.u8 != 0)
	{
		D0.u8 = D6.u8 & object.flag.P1_ON_OBJECT
		if (D0.u8 != 0)
		{
			A4 = A0 + 0x2e
			A1 = 0xffffb000
			D6 = 3		// object.flag.P1_ON_OBJECT
			fn028f40()
		}

		D6.u8 &= object.flag.P2_ON_OBJECT
		if (D6.u8 != 0)
		{
			A4 = A0 + 0x2f
			A1 = 0xffffb04a
			D6 = 4		// object.flag.P2_ON_OBJECT
			fn028f40()
		}
	}

	DrawOrUnloadObject()
}


//# address-hook(0x028e76) end(0x028f3e)
function void fn028e76()
{
	if ((objA0.flags2a & 0x01) == 0)
	{
		D0.u16 = objA1.position.x.u16 - objA0.position.x.u16 + 0x18
		if (D0.u16 >= 0x30)
			return

		D0.u16 = objA0.position.x.u16 + 0x10
	}
	else
	{
		D0.u16 = objA0.position.x.u16 - objA1.position.x.u16 + 0x18
		if (D0.u16 >= 0x30)
			return

		D0.u16 = objA0.position.x.u16 - 0x10
	}

	objA1.position.x.u16 = D0.u16
	objA1.position.y.u16 = objA0.position.y.u16
	objA1.velocity.x = 0
	objA1.velocity.y = -0xa00
	u16[A1 + 0x1c] = 0x800
	objA1.hitbox_extends.y = char.hitbox.y.ROLLING
	objA1.hitbox_extends.x = char.hitbox.x.ROLLING
	objA1.state = char.state.ROLLING
	objA1.flags2a |= (char.flag.IN_AIR | char.flag.ROLLING)
	u8[A1 + 0x40] = 0

	u8[A4] = 0x10
}


//# address-hook(0x028f40) end(0x028ff2)
function void fn028f40()
{
	u8 bit = (1 << D6.u8)

	if ((objA0.flags2a & 0x01) == 0)
	{
		D0.u16 = objA1.position.x.u16 - objA0.position.x.u16
		if (D0.u16 >= 0x20)
			return

		D0.u16 = objA0.position.x.u16 + 0x10
	}
	else
	{
		D0.u16 = objA0.position.x.u16 - objA1.position.x.u16
		if (D0.u16 >= 0x20)
			return

		D0.u16 = objA0.position.x.u16 - 0x10
	}

	objA1.position.x.u16 = D0.u16
	objA1.velocity.x = 0
	objA1.velocity.y = 0
	objA1.groundspeed = 0
	u8[A1 + 0x2a] |= char.flag.IN_AIR
	u8[A1 + 0x2a] &= ~(char.flag.ON_OBJECT | char.flag.ROLLING)
	u8[A1 + 0x40] = 0
	u8[A1 + 0x20] = 0
	objA0.flags2a &= ~bit
	u8[A4] = 0x20
}
